# _*_ coding: utf8 _*_
import json
import random
import re
import time

from django.contrib import auth
from django.contrib.auth.models import User
from django.core import serializers
from django.http import HttpResponseRedirect, JsonResponse, HttpResponseForbidden, HttpResponse
from django.middleware.csrf import get_token
from django.shortcuts import render
from rest_framework.decorators import api_view

from accounts.models import UserProfile
from student.models import Student
from teacher.models import Teacher
from teacher.utils import create_teacher
from tools.err import RoingException, ErrorLoginPasswordIncorrect, ErrorLoginInvalidVerifyCode, ErrorDoesNotExist, \
    ErrorLoginVerifyFail
from tools.message import send_verify_code_to, real_verify_code
from tools.util import app_info
from .serializers import UserSeri, UserProfileSeri
from .util import upload_file_data, params_of_request


# Create your views here.

def profile(request):
    user_id = request.GET.get('id', 0)
    teacher_id = request.GET.get('teacher_id', 0)
    student_id = request.GET.get('student_id', 0)

    user = {}

    try:
        if user_id:
            user = User.objects.get(pk=user_id)
        elif teacher_id:
            user = Teacher.objects.get(pk=teacher_id).me
        else:
            user = Student.objects.get(pk=student_id).me
    except Exception as e:
        pass

    return render(request, 'profile.html', {'user': request.user, 'profileuser': user})


def profile_data(request):
    response = {}

    user_id = request.GET.get('id', 0)
    try:
        user = User.objects.get(pk=user_id)
        response['user'] = json.loads(serializers.serialize('json', [user]))
    except Exception as e:
        response['msg'] = str(e)

    return JsonResponse(response)


def update(request):
    if request.method == 'POST':
        first_name = request.POST.get('first_name', '')
        last_name = request.POST.get('last_name', '')
        icon = upload_file_data(request.FILES.get('icon', None))
        age = request.POST.get('age', '')
        phone = request.POST.get('phone', '')
        desc = request.POST.get('desc', '')

        userprofile = request.user.userprofile
        if age:
            userprofile.age = age
        if phone:
            userprofile.phone = phone
        if desc:
            userprofile.desc = desc
        if icon:
            import os
            fileurl = os.path.join(userprofile.icon.field.upload_to, icon[1])
            userprofile.icon.name = fileurl
        user = request.user
        user.first_name = first_name
        user.last_name = last_name
        user.userprofile = userprofile
        user.save()
        return HttpResponseRedirect('/accounts/profile?id=' + str(user.pk))

    return HttpResponseForbidden(u'权限不够')


def login_view(request):
    params = params_of_request(request)
    user_name = params.get('user-name', '')
    passwd = params.get('password', '')
    stay = params.get('stay', False)
    user = auth.authenticate(username=user_name, password=passwd)

    if user_name is not None and user is not None and user.is_active:
        auth.login(request, user)
        if stay:
            return JsonResponse({'user': json.loads(serializers.serialize('json', [user]))[0]})
        else:
            return HttpResponseRedirect('/school')
    return render(request, 'login_view.html', {})


@api_view(['POST', 'GET'])
def c_login(request):
    try:
        response = {}
        if request.user.is_active:
            response = {'user': UserSeri(request.user).data}
            return JsonResponse(response, safe=False)
        params = request.data
        user_name = params.get('username', '')
        passwd = params.get('password', '')
        veri_code = params.get('verify_code', None)

        if passwd:
            user = auth.authenticate(username=user_name, password=passwd)
        elif veri_code:
            real_code = real_verify_code(veri_code)
            user = User.objects.get(username=user_name)
            if user.userprofile.verify_code != real_code:
                raise RoingException(message=u'验证码无效', code=ErrorLoginInvalidVerifyCode)
            else:
                user.backend = 'django.contrib.auth.backends.ModelBackend'
        else:
            raise RoingException(message=u'请输入有效的密码', code=612)

        if user_name is not None and user is not None and user.is_active:
            auth.login(request, user)
            response = {'user': UserSeri(request.user).data}
            response['user']['has_password'] = user.has_usable_password()
            response['user']['X-CSRFToken'] = get_token(request)
            return JsonResponse(response, safe=False)
        else:
            User.objects.get(username=user_name)
            raise RoingException(message=u'用户名密码不匹配', code=ErrorLoginPasswordIncorrect)
    except User.DoesNotExist as e:
        raise RoingException(message=u'无此账号，请使用验证码登录', code=601)
    except Exception as e:
        raise e
    return JsonResponse({'msg': 'error'})


@api_view(['POST'])
def c_check_verify(request):
    code = request.data.get('verify_code', None)
    if code:
        real_code = real_verify_code(code)

        try:
            user_name = request.data.get('username', '')
            user = User.objects.get(username=user_name)
            if user.userprofile.verify_code == real_code:
                return JsonResponse(UserSeri(user).data)
        except Exception as e:
            raise RoingException(message='参数错误', code=ErrorDoesNotExist)

    raise RoingException(message=u'无效的验证码', code=ErrorLoginInvalidVerifyCode)


@api_view(['POST'])
def c_password_reset(request):
    passwd = request.data.get('password', '')
    user_name = request.data.get('username', '')

    try:
        user = User.objects.get(username=user_name)
        user.set_password(passwd)
        user.save()

        return JsonResponse(UserSeri(user).data, safe=False)
    except Exception as e:
        raise RoingException(message=str(e), code=601)


def c_apply(request):
    params = params_of_request(request)
    user_name = params.get('username', None)
    password = params.get('password', None)

    if not user_name or not password:
        return HttpResponse(status=612)

    try:
        User.objects.get(username=user_name)
        return HttpResponse(status=613)
    except User.DoesNotExist as e:
        try:
            user = User.objects.create(username=user_name)
            user.set_password(password)
            user.save()
        except Exception as e:
            return HttpResponse(status=614)
        return JsonResponse({})


@api_view(['GET', 'POST'])
def c_msg_verify(request):
    params = params_of_request(request)
    phone = params.get('phone', None)
    if not phone:
        return JsonResponse({'error': -1, 'msg': '没有手机号'})

    p2 = re.compile('^0\d{2,3}\d{7,8}$|^1[358]\d{9}$|^147\d{8}')
    phonematch = p2.match(phone)
    if not phonematch:
        return JsonResponse({'error': -1, 'msg': '手机号无效'})

    code = str(random.random())[-4:]
    try:
        user = User.objects.get(username=phone)
    except User.DoesNotExist as e:
        user = User.objects.create_user(username=phone, first_name='老师' + str(phone[-4:]))
        UserProfile.objects.create(user=user, phone=phone).save()
        # 新出现的用户直接分为老师类
        create_teacher(user)

    if not send_verify_code_to(code, phone):
        raise RoingException(message='验证码发送失败', code=ErrorLoginVerifyFail)

    user.userprofile.verify_code = real_verify_code(code)
    user.userprofile.save()

    # 兼容旧版本
    version = app_info(request)
    if version < '1.2.9':
        user.set_password(code)
        user.save()
    return JsonResponse({'error': 0})


def c_logout(request):
    try:
        auth.logout(request)
    except Exception as e:
        pass
    return JsonResponse({'msg': 'logout success'})


def c_search(request):
    params = params_of_request(request)
    user_name = params.get('user', {}).get('username', None)
    if user_name:
        try:
            us = User.objects.filter(username__icontains=user_name)
            us_first_name = User.objects.filter(first_name__icontains=user_name)
            us_all = us | us_first_name
            return JsonResponse({'users': UserSeri(us_all, many=True).data}, safe=False)
        except Exception as e:
            pass
    return JsonResponse({'users': []})


@api_view(['GET', 'POST'])
def c_update_seri(request):
    user_data = request.data.get('user', {})
    user = User.objects.filter(pk=int(user_data.get('pk', 0)))
    if user:
        user = user[0]

    profile_data = user_data.get('userprofile', {})
    profile_data.pop('icon', {})

    seri = UserSeri(user, user_data)

    if seri.is_valid():
        seri.save()
    else:
        raise RoingException(message=seri.errors, code=601)
    return JsonResponse(seri.data, safe=False)


def c_update(request):
    try:
        params = params_of_request(request).get('user', {})
        uprofile = params.get('userprofile', {})
        if params:
            first_name = params.get('first_name', '')
            last_name = params.get('last_name', '')
            # icon = upload_file_data(request.FILES.get('icon', None))
            age = uprofile.get('age', '')
            phone = uprofile.get('phone', '')
            desc = uprofile.get('desc', '')

            if not hasattr(request.user, 'userprofile'):
                userprofile = UserProfile.objects.create(user=request.user)
            else:
                userprofile = request.user.userprofile
            if age:
                userprofile.age = age
            if phone:
                userprofile.phone = phone
            if desc:
                userprofile.desc = desc
            userprofile.save()

            # if icon:
            #     import os
            #     fileurl = os.path.join(userprofile.icon.field.upload_to, icon[1])
            #     userprofile.icon.name = fileurl

            user = request.user
            user.first_name = last_name + first_name
            user.last_name = ''
            user.userprofile = userprofile
            user.save()
            return JsonResponse(UserSeri(user).data, safe=False)
    except Exception as e:
        return JsonResponse({'msg': str(e)})
    return HttpResponse()


def logout_view(request):
    auth.logout(request)
    return HttpResponseRedirect('/accounts/login')


def current_user(request):
    if not request.user.is_active:
        return JsonResponse({'user': {'X-CSRFToken': get_token(request)}})
    user_res = UserSeri(request.user).data
    user_res['X-CSRFToken'] = get_token(request)
    return JsonResponse({'user': user_res})
